package org.zhxy.config.mvc;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.zhxy.model.exception.BizException;
import org.zhxy.model.result.Result;
import org.zhxy.model.result.ResultCode;

import java.util.stream.Collectors;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 处理 JavaBean 数据校验异常
    // 适用于将请求体或 URL 参数封装成 JavaBean 的情况
    @ExceptionHandler(value = BindException.class)
    public String handleBindException(BindException ex) {
        String msg = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining("; "));
        log.error("参数校验异常：{}", msg, ex);
        return msg;
    }

    // 处理 String、包装类数据校验
    // 适用于 @RequestParam、@PathVariable 的情况
    @ExceptionHandler(ConstraintViolationException.class)
    public String handleConstraintViolationException(ConstraintViolationException ex) {
        String msg = ex.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining("; "));
        log.error("参数校验异常：{}", msg, ex);
        return msg;
    }

    // 业务异常处理
    @ExceptionHandler(BizException.class)
    public Result handleBizException(BizException ex) {
        log.warn("业务异常处理：{}", ex.getMessage(), ex);
        ResultCode resultCode = ex.getResultCode();
        if (resultCode == ResultCode.ERROR) {
            // 返回未归档的错误信息
            return Result.error(ex.getMessage());
        }
        // 返回已归档的错误信息
        return Result.error(ex.getResultCode());
    }

    // 默认异常处理
    @ExceptionHandler(Exception.class)
    // @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handleException(Exception ex) {
        log.error("默认异常处理：{}", ex.getMessage(), ex);
        return Result.error(ex.getMessage());
    }
}